package com.rzt.cft.admin.controller.uc;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rzt.cft.admin.controller.BaseController;
import com.rzt.cft.constant.ServiceStatus;
import com.rzt.cft.constant.StatusConstant;
import com.rzt.cft.constant.TypeConstant;
import com.rzt.cft.dto.ResponseData;
import com.rzt.cft.dto.uc.*;
import com.rzt.cft.entity.project.ProjectOrder;
import com.rzt.cft.entity.uc.*;
import com.rzt.cft.param.IdParam;
import com.rzt.cft.param.uc.*;
import com.rzt.cft.service.project.IProjectOrderService;
import com.rzt.cft.service.uc.*;
import com.rzt.cft.utils.CustomUtil;
import com.rzt.cft.utils.Md5Utils;
import com.rzt.cft.utils.ParseWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * @author 钟忠
 * @date 2020/2/5 11:51
 */
@RestController
@RequestMapping("/v1/uc-user")
@Api(tags = "前端用户相关接口")
@Slf4j
public class UcUserController extends BaseController {

    @Autowired
    private IUcUserService ucUserService;

    @Autowired
    private IUcAssetService ucAssetService;

    @Autowired
    private IUcRechargeService ucRechargeService;

    @Autowired
    private IUcWithdrawService ucWithdrawService;

    @Autowired
    private IUcLogoutService ucLogoutService;

    @Autowired
    private IUcReceivingAddressService ucReceivingAddressService;

    @Autowired
    private IUcWalletService ucWalletService;

    @Autowired
    private IUcAssetStatisticsService ucAssetStatisticsService;

    @Autowired
    private IUcAccountService ucAccountService;

    @Autowired
    private IUcDistributionTypeService ucDistributionTypeService;

    @Autowired
    private IUcUserDistributionLogService ucUserDistributionLogService;

    @Autowired
    private IProjectOrderService projectOrderService;

    @Autowired
    private IUcRebateLogService ucRebateLogService;


    @ApiOperation("用户列表(分页)")
    @PostMapping("/list")
    public ResponseData<IPage<UcUserDto>> list(@RequestBody UcUserParam para) {
        Page page = getPage(para);
        QueryWrapper<UcUser> queryWrapper =  ParseWrapper.parseWrapper(para);
        queryWrapper.orderByDesc("create_at");
        IPage<UcUser> pageUser = ucUserService.page(page, queryWrapper);
        List<String> ids = CustomUtil.select(pageUser.getRecords(), UcUser::getId);
        if (ids.size() == 0) {
            return success(pageUser.convert(x -> CustomUtil.maping(x, UcUserDto.class)));
        }
        QueryWrapper<UcAsset> ucAssetQueryWrapper =  new QueryWrapper<>();
        ucAssetQueryWrapper.eq("current", true);
        ucAssetQueryWrapper.in("user_id", ids);
        List<UcAsset> ucAssets = ucAssetService.list(ucAssetQueryWrapper);
        IPage<UcUserDto> userDtoIPage = pageUser.convert(x -> CustomUtil.maping(x, UcUserDto.class));
        userDtoIPage.getRecords().forEach(x -> {
            UcAsset ucAsset = CustomUtil.first(ucAssets, m -> m.getUserId().equals(x.getId()));
            if (Objects.nonNull(ucAsset)) {
                x.setInvestment(ucAsset.getInvestment());
                x.setUsable(ucAsset.getUsable());
                x.setIntegral(ucAsset.getIntegral());
            }
        });
        return success(userDtoIPage);
    }

    @ApiOperation("用户详情")
    @PostMapping("/detail")
    public ResponseData<UcUserDetailDto> list(@RequestBody IdParam param) {
        UcUser ucUser = ucUserService.getById(param.getId());
        if (Objects.isNull(ucUser)) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }
        UcUserDetailDto ucUserDetailDto = CustomUtil.maping(ucUser, UcUserDetailDto.class);
        QueryWrapper queryWrapper =  new QueryWrapper<>();
        queryWrapper.in("user_id", param.getId());
        List<UcReceivingAddress> ucReceivingAddresses = ucReceivingAddressService.list(queryWrapper);
        if (ucReceivingAddresses != null && ucReceivingAddresses.size() > 0) {
            ucUserDetailDto.setReceivingAddressDtos(CustomUtil.maping(ucReceivingAddresses, UcReceivingAddressDto.class));
        }

        List<UcWallet> ucWallets = ucWalletService.list(queryWrapper);
        if (ucWallets != null && ucWallets.size() > 0) {
            ucUserDetailDto.setUcWalletDtos(CustomUtil.maping(ucWallets, UcWalletDto.class));
        }

        QueryWrapper<UcAssetStatistics> statisticsQueryWrapper =  new QueryWrapper<>();
        statisticsQueryWrapper.eq("user_id", param.getId());
        statisticsQueryWrapper.eq("current", true);
        UcAssetStatistics ucAssetStatistics = ucAssetStatisticsService.getOne(statisticsQueryWrapper);
        if (Objects.nonNull(ucAssetStatistics)) {
            ucUserDetailDto.setAccumulationIntegral(ucAssetStatistics.getAccumulationIntegral());
            ucUserDetailDto.setAccumulationInjection(ucAssetStatistics.getAccumulationInjection());
            ucUserDetailDto.setAccumulationRebate(ucAssetStatistics.getAccumulationRebate());
        }
        return success(ucUserDetailDto);
    }

    @ApiOperation("查看伞下")
    @PostMapping("/childList")
    public ResponseData<List<UcUserDto>> childList(@RequestBody IdParam param) {
        QueryWrapper<UcUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", param.getId());
        List<UcUser> ucUser = ucUserService.list(queryWrapper);
        return success(CustomUtil.maping(ucUser, UcUserDto.class));
    }

    @ApiOperation("余额管理（加减余额）")
    @PostMapping("/balanceManage")
    public ResponseData<Boolean> balanceManage(@RequestBody BalanceManageParam param) {
        UcUser ucUser = ucUserService.getById(param.getId());
        if (Objects.isNull(ucUser)) {
            return fail(ServiceStatus.NO_USER);
        }
        InsertUsableParam usableParam = new InsertUsableParam();
        usableParam.setType(TypeConstant.usableChangeType.BALANCE_MANAGEMENT);
        usableParam.setUsable(param.getAccount());
        usableParam.setUserId(ucUser.getId());
        usableParam.setUserName(ucUser.getNickName());
        Boolean result = ucAssetService.insertUsable(usableParam);
        return success(result);
    }

    @ApiOperation("充值审核列表")
    @PostMapping("/recharge/list")
    public ResponseData<IPage<UcRechargeDto>> rechargeList(@RequestBody ExaminePageParam para) {
        Page page = getPage(para);
        QueryWrapper<UcRecharge> queryWrapper =  ParseWrapper.parseWrapper(para);
        queryWrapper.orderByDesc("create_at");
        IPage<UcRecharge> ucRechargeIPage = ucRechargeService.page(page, queryWrapper);
        List<String> ids = CustomUtil.select(ucRechargeIPage.getRecords(), UcRecharge::getUserId);
        IPage<UcRechargeDto> rechargeDtoIPage = ucRechargeIPage.convert(x -> CustomUtil.maping(x, UcRechargeDto.class));
        List<UcUser> ucUser = ucUserService.listByIds(ids);
        rechargeDtoIPage.getRecords().forEach(x -> {
            UcUser user = CustomUtil.first(ucUser, m -> x.getUserId().equals(m.getId()));
            if (Objects.nonNull(user)) {
                x.setUserName(user.getNickName());
            }
        });
        return success(rechargeDtoIPage);
    }

    @ApiOperation("充值审核")
    @PostMapping("/recharge/examine")
    public ResponseData<Boolean> rechargeExamine(@RequestBody ExamineParam para) {
        UcRecharge ucRecharge = ucRechargeService.getById(para.getId());
        if (Objects.isNull(ucRecharge)) {
            return fail(ServiceStatus.NO_RELATED_AUDITS_FOUND);
        }
        if (!ucRecharge.getStatus().equals(StatusConstant.UcRechargeStatus.WAIT_AUDITED)) {
            return fail(ServiceStatus.ORDER_APPROVED);
        }
        Boolean resulr = ucRechargeService.rechargeExamine(para, ucRecharge);
        return success(resulr);
    }

    @ApiOperation("提现审核列表")
    @PostMapping("/withdraw/list")
    public ResponseData<IPage<UcWithdrawDto>> withdrawList(@RequestBody ExaminePageParam para) {
        Page page = getPage(para);
        QueryWrapper<UcWithdraw> queryWrapper =  ParseWrapper.parseWrapper(para);
        queryWrapper.orderByDesc("create_at");
        IPage<UcWithdraw> ucRechargeIPage = ucWithdrawService.page(page, queryWrapper);
        List<String> ids = CustomUtil.select(ucRechargeIPage.getRecords(), UcWithdraw::getUserId);
        IPage<UcWithdrawDto> withdrawDtoIPage = ucRechargeIPage.convert(x -> CustomUtil.maping(x, UcWithdrawDto.class));
        List<UcUser> ucUser = ucUserService.listByIds(ids);
        withdrawDtoIPage.getRecords().forEach(x -> {
            UcUser user = CustomUtil.first(ucUser, m -> x.getUserId().equals(m.getId()));
            if (Objects.nonNull(user)) {
                x.setUserName(user.getNickName());
            }
        });
        return success(withdrawDtoIPage);
    }

    @ApiOperation("提现审核")
    @PostMapping("/withdraw/examine")
    public ResponseData<Boolean> withdrawExamine(@RequestBody ExamineParam para) {
        UcWithdraw ucWithdraw = ucWithdrawService.getById(para.getId());
        if (Objects.isNull(ucWithdraw)) {
            return fail(ServiceStatus.NO_RELATED_AUDITS_FOUND);
        }
        if (!ucWithdraw.getStatus().equals(StatusConstant.UcRechargeStatus.WAIT_AUDITED)) {
            return fail(ServiceStatus.ORDER_APPROVED);
        }
        Boolean resulr = ucWithdrawService.withdrawExamine(para, ucWithdraw);
        return success(resulr);
    }

    @ApiOperation("退出审核列表")
    @PostMapping("/logout/list")
    public ResponseData<IPage<UcLogoutDto>> logoutList(@RequestBody ExaminePageParam para) {
        Page page = getPage(para);
        QueryWrapper<UcLogout> queryWrapper =  ParseWrapper.parseWrapper(para);
        queryWrapper.orderByDesc("create_at");
        IPage<UcLogout> ucLogoutIPage = ucLogoutService.page(page, queryWrapper);
        List<String> ids = CustomUtil.select(ucLogoutIPage.getRecords(), UcLogout::getUserId);
        IPage<UcLogoutDto> logoutDtoIPage = ucLogoutIPage.convert(x -> CustomUtil.maping(x, UcLogoutDto.class));
        List<UcUser> ucUser = ucUserService.listByIds(ids);
        logoutDtoIPage.getRecords().forEach(x -> {
            UcUser user = CustomUtil.first(ucUser, m -> x.getUserId().equals(m.getId()));
            if (Objects.nonNull(user)) {
                x.setUserName(user.getNickName());
            }
        });
        return success(logoutDtoIPage);
    }

    @ApiOperation("退出审核")
    @PostMapping("/logout/examine")
    public ResponseData<Boolean> logoutExamine(@RequestBody ExamineParam para) {
        UcLogout ucLogout = ucLogoutService.getById(para.getId());
        if (Objects.isNull(ucLogout)) {
            return fail(ServiceStatus.NO_RELATED_AUDITS_FOUND);
        }
        if (!ucLogout.getStatus().equals(StatusConstant.UcRechargeStatus.WAIT_AUDITED)) {
            return fail(ServiceStatus.ORDER_APPROVED);
        }
        if (!para.getStatus().equals(StatusConstant.UcRechargeStatus.ADOPT)
                && !para.getStatus().equals(StatusConstant.UcRechargeStatus.REJECTED)) {
            return fail(ServiceStatus.AUDIT_STATUS_ERROR);
        }
        //校验7天时间
        LocalDateTime overdue = ucLogout.getApplyTime().plusDays(7);
        if (overdue.isBefore(LocalDateTime.now())) {
            return fail(ServiceStatus.SEVEN_DAYS_TO_REVIEW);
        }
        Boolean resulr = ucLogoutService.logoutExamine(para, ucLogout);
        return success(resulr);
    }

    /**
     * 重置用户密码
     * @param param
     * @return
     */
    @ApiOperation( "重置用户密码")
    @PostMapping("resetPassword")
    public ResponseData<Boolean> resetPassword(@RequestBody ResetPwdParam param) {
        UcAccount ucAccount = ucAccountService.findOneByKv("user_id", param.getUserId());
        if (Objects.isNull(ucAccount)) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }
        String pw = Md5Utils.shiroMD5(ucAccount.getSalt(), param.getPwd());
        ucAccount.setPassword(pw);
        Boolean result = ucAccountService.updateById(ucAccount);
        return success(result);
    }


    /**
     * 修改会员等级
     * @param param
     * @return
     */
    @ApiOperation( "修改会员等级")
    @PostMapping("modifyLevel")
    public ResponseData<Boolean> modifyLevel(@RequestBody ModifyLevelParam param) {
        UcUser ucUser = ucUserService.getById(param.getUserId());
        if (Objects.isNull(ucUser)) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }
        UcDistributionType distributionType = ucDistributionTypeService.getById(param.getTypeId());
        if (Objects.isNull(distributionType)) {
            return fail(ServiceStatus.PARAM_EXCEPTION);
        }

        ucUser.setDistributionId(distributionType.getId());
        ucUser.setDistributionName(distributionType.getName());
        ucUserService.updateById(ucUser);

        UcUserDistributionLog ucUserDistributionLog = new UcUserDistributionLog();
        ucUserDistributionLog.setUserId(ucUser.getId());
        ucUserDistributionLog.setDistributionId(distributionType.getId());
        ucUserDistributionLogService.save(ucUserDistributionLog);

        return success(null);
    }



    @PostMapping("/test")
    public void intelligenceRebate() {
        log.info("每天凌晨执行智能返利 定时执行 。。。。。............... : {}" , LocalDateTime.now());
        //查询当天还在进行中的智能项目订单
        QueryWrapper<ProjectOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", StatusConstant.ProjectOrderStatus.IN_HAND);
        queryWrapper.eq("project_type", TypeConstant.projectType.INTELLIGENCE);
        List<ProjectOrder> projectOrderList = projectOrderService.list(queryWrapper);
        projectOrderList.forEach(x -> {
            ucRebateLogService.intelligenceRebate(x);
        });
    }


    @PostMapping("/test2")
    public void optionalRebate() {
        log.info("每个小时执行一次自选返利 定时执行 。。。。。............... : {}" , LocalDateTime.now());
        //查询当天还在进行中的智能项目订单
        QueryWrapper<ProjectOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", StatusConstant.ProjectOrderStatus.IN_HAND);
        queryWrapper.eq("project_type", TypeConstant.projectType.OPTIONAL);
        queryWrapper.le("completion_time", LocalDateTime.now());
        List<ProjectOrder> projectOrderList = projectOrderService.list(queryWrapper);
        projectOrderList.forEach(x -> {
            ucRebateLogService.optionalRebate(x);
        });
    }


}
